//TODO 统一的超时和中断机制

export const domain = 'http://localhost:8686';

export const checkStatus = (response) => {
    if ((response.code >= 200 && response.code <= 300) || (response.status >= 200 && response.status <= 300)) {
        return response;
    }
    const error = new Error(response.msg);
    error.response = response;
    throw error;
};

export const toGetParam = (json) => (
    Object.keys(json).map(function (key) {
        return encodeURIComponent(key) + "=" + encodeURIComponent(json[key]);
    }).join("&")
);

export const get = (url, param, page) => {
    let _param = {};
    //TODO 校验其他参数的有效性
    if (page != null && page != undefined) {
        _param = Object.assign(param, page)
    }
    //TODO 优化 http get 请求构造参数
    return fetch(url + '?' + toGetParam(_param), {
        method: 'GET',
        body: undefined,
        dataType: "json",
    }).then(response => response.json()).then(data => {
        return checkStatus(data);
    }).catch(function (err) {
        console.log("Fetch错误:" + err);
        //TODO 统一的错误处理机制
    });
};

export const put = (url, param) => {
    return fetch(url, {
        method: 'PUT',
        body: JSON.stringify(param),
        headers: {
            "Content-Type": "application/json"
        },
        dataType: "json",
    }).then(response => response.json()).then(data => {
        return checkStatus(data);
        ;
    }).catch(function (err) {
        console.log("Fetch错误:" + err);
    });
};

export const post = (url, param) => {
    return fetch(url, {
        method: 'POST',
        body: JSON.stringify(param),
        headers: {
            "Content-Type": "application/json"
        },
        dataType: "json",
    }).then(response => response.json()).then(data => {
        return checkStatus(data);
        ;
    }).catch(function (err) {
        console.log("Fetch错误:" + err);
    });
};

export const patch = (url, param) => {
    return fetch(url, {
        method: 'PATCH',
        body: JSON.stringify(param),
        headers: {
            "Content-Type": "application/json"
        },
        dataType: "json",
    }).then(response => response.json()).then(data => {
        return checkStatus(data);
        ;
    }).catch(function (err) {
        console.log("Fetch错误:" + err);
    });
};

export const del = (url, param) => {
    return fetch(url, {
        method: 'DELETE',
        body: JSON.stringify(param),
        headers: {
            "Content-Type": "application/json"
        },
        dataType: "json",
    }).then(response => response.json()).then(data => {
        return checkStatus(data);
        ;
    }).catch(function (err) {
        console.log("Fetch错误:" + err);
    });
};

export const downloadBinaryResource = (url) => {
    return new Promise((resolve, reject) => {
        let newOptions = {};
        //TODO 可能需要修改获取access_token的方式
        if (localStorage.getItem('access_token') != null && localStorage.getItem('access_token') != undefined) {
            newOptions.headers = {
                Authorization: 'Bearer ' + localStorage.getItem('access_token'),
                ...newOptions.headers,
            };
        }

        let xmlRequest = new XMLHttpRequest();
        xmlRequest.open('GET', url, true);
        xmlRequest.setRequestHeader('Authorization', newOptions.headers.Authorization);
        xmlRequest.responseType = 'blob';//指明返回的数据的类型是二进制
        xmlRequest.onload = function (e) {
            if (this.readyState == 4 && this.status == 200) {
                resolve(xmlRequest.response);
            }
        };
        xmlRequest.send(null);
    });
};

/**
 * 获取资源文件二进制内容
 *
 * @param url
 * @returns {Promise<T | never | void>}
 */
export const requestBinaryResource = (url) => {
    return downloadBinaryResource(url)
        .then(result => {
            return result;
        })
        .catch(error => console.log(error));
};

/**
 * 下载二进制内容
 *
 * @param blob
 * @param fileName
 * @param suffix
 */
export const downloaFile = (blob, fileName, suffix) => {
    let a = document.createElement('a');
    a.innerHTML = 'download';
    // 指定生成的文件名
    a.download = fileName + '.' + suffix;
    a.href = URL.createObjectURL(blob);
    document.body.appendChild(a);
    let evt = document.createEvent('MouseEvents');
    evt.initEvent('click', false, false);
    a.dispatchEvent(evt);
    document.body.removeChild(a);
};

export class URL {
    url = '';
    part = {}
    param = {};
    page = {};

    constructor(url) {
        this.url = domain + url;
    }

    setPart(part) {
        Object.keys(part).map(key => (
            {'partKey': key, 'urlKey': `{${key}}`}
        )).map(item => {
            this.url = this.url.replace(item.urlKey, part[item.partKey])
        });
        return this;
    }

    setParameters(param) {
        this.param = param;
        return this;
    }

    setPage(page) {
        this.page = page;
        return this;
    }

    post() {
        return post(this.url, this.param)
    };

    delete() {
        return del(this.url, this.param)
    };

    put() {
        return put(this.url, this.param)
    };

    patch() {
        return patch(this.url, this.param)
    };

    get() {
        return get(this.url, this.param, this.page)
    };

}
